/* 
 * TileDataLoader
 * and open the template in the editor.
 */
/**
 * setMap(map)
 * startAutoLoadData()
 * stopAutoLoadData()
 * getTileURL(tilecode);  + ?params
 * getCacheKey(tilecode); + ?params
 * clearMap()
 * reload();
 * generateEntity(dataOfElement);
 * generateGroupEntity(dataOfElement);
 * onTileLoaded(json_data); + ?params
 * /////////////////////////////
 * ?setLoadParams(params)
 */

var TileDataLoader = function(params){    
    
    var map = null;
    var dataCache = {};  //   {cacheZone}=>[zoom]=>{key1=>val1, key2=>val2 ...}
    var requests = {};
    var visibleEntities = [];
    var visibleTiles={};    
    function getCacheZone(){
        return 'default'; // zaglushka
    }
    function getCache(){        
        if(typeof dataCache[getCacheZone()]!='object')
            dataCache[getCacheZone()] = {};
        return dataCache[getCacheZone()];
    }
    function zoom(){
        return map.getZoom();
    }
    function getFromCache(tilecode){        
        if(typeof getCache()[getCacheKey(tilecode)] !='undefined' )
            return getCache()[getCacheKey(tilecode)] ; 
        return false;
    }
    function setCache(tilecode, data){   
        getCache()[getCacheKey(tilecode)] = data;
    }
    function loadData(){       
        map.getVisibleTilesInQuadTreeList(zoom()).map(function(tile){
             var _data_ = getFromCache(tile);
             
                if(_data_){
                    if(visibleTiles[getCacheKey(tile)]) return;
                    _data_.map(function(en){
                        visibleEntities.push(en);
                        en.setMap(map);
                    });
                    visibleTiles[getCacheKey(tile)] = true;
                }
                else{                    
                    if(!requests[tile])
                        requests[tile] = $.ajax({
                           url:getTileUrl(tile),
                           success:tileDidLoad.bind({tile:tile}),
                           dataType:'json'
                        });
                }
           });
     }
     function getCacheKey(tilecode){
               return 't'+tilecode;
     }
     function getTileUrl(tileQuadCode){
        return '/ajax/map/tile?code='+tileQuadCode;
     }
     
     function tileDidLoad(resp){
        setCache(this.tile, _interface.tileDidLoad(resp, this.tile)); 
        visibleTiles[getCacheKey(this.tile)] = true;
     } 
     function pushEntity(en){
         visibleEntities.push(en);
         return en;
     }
     function clearMap(){
               var en;
               while( en = visibleEntities.pop())
                   en.setMap(null);
               visibleTiles={};
      }
      function setMap(map_){
          map = map_;
          map.bindEvent('drag',loadData); 
          map.bindEvent('zoom_changed',function(){
              clearMap();
              loadData();
          }); 
          loadData();
      }
      function getMap(){
          return map;
      }
      var _interface = {
        pushEntity:pushEntity,
        getMap:getMap,
        generateEntity:function(id, dataOfElement){
//            var en =  new Advert({_id:id, loc:dataOfElement});
            var en =  new Advert({_id:id, lat:dataOfElement[1], lng:dataOfElement[0],count:dataOfElement[2]});
            en.setMap(this.getMap());
            return en;
        },
        setMap:setMap,
        tileDidLoad:
            function(resp){
                var markers = [];
                var key;
                for(key in resp)
                    markers.push(this.pushEntity(this.generateEntity(key, resp[key])));
                
                return markers;
            }
     };
     
     return _interface;
}
